home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_Widget.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  5.5 KB  |  201 lines

  1. //
  2. // "$Id: Fl_Widget.cxx,v 1.5 1999/01/07 19:17:29 mike Exp $"
  3. //
  4. // Base widget class for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include <FL/Fl.H>
  27. #include <FL/Fl_Widget.H>
  28. #include <FL/Fl_Group.H>
  29.  
  30. ////////////////////////////////////////////////////////////////
  31. // for compatability with Forms, all widgets without callbacks are
  32. // inserted into a "queue" when they are activated, and the forms
  33. // compatability interaction functions (fl_do_events, etc) will
  34. // read one widget at a time from this queue and return it:
  35.  
  36. const int QUEUE_SIZE = 20;
  37.  
  38. static Fl_Widget *obj_queue[QUEUE_SIZE];
  39. static int obj_head, obj_tail;
  40.  
  41. void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
  42. #if 0
  43.   // This is necessary for strict forms compatability but is confusing.
  44.   // Use the parent's callback if this widget does not have one.
  45.   for (Fl_Widget *p = o->parent(); p; p = p->parent())
  46.     if (p->callback() != default_callback) {
  47.       p->do_callback(o,v);
  48.       return;
  49.     }
  50. #endif
  51.   obj_queue[obj_head++] = o;
  52.   if (obj_head >= QUEUE_SIZE) obj_head = 0;
  53.   if (obj_head == obj_tail) {
  54.     obj_tail++;
  55.     if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
  56.   }
  57. }
  58.  
  59. Fl_Widget *Fl::readqueue() {
  60.   if (obj_tail==obj_head) return 0;
  61.   Fl_Widget *o = obj_queue[obj_tail++];
  62.   if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
  63.   return o;
  64. }
  65.     
  66. ////////////////////////////////////////////////////////////////
  67.  
  68. int Fl_Widget::handle(int) {return 0;}
  69.  
  70. Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
  71.  
  72.   x_ = X; y_ = Y; w_ = W; h_ = H;
  73.  
  74.   label_.value    = L;
  75.   label_.type    = FL_NORMAL_LABEL;
  76.   label_.font    = FL_HELVETICA;
  77.   label_.size    = FL_NORMAL_SIZE;
  78.   label_.color    = FL_BLACK;
  79.   callback_    = default_callback;
  80.   user_data_     = 0;
  81.   type_        = 0;
  82.   flags_    = 0;
  83.   damage_    = 0;
  84.   box_        = FL_NO_BOX;
  85.   color_    = FL_GRAY;
  86.   color2_    = FL_GRAY;
  87.   align_    = FL_ALIGN_CENTER;
  88.   when_        = FL_WHEN_RELEASE;
  89.  
  90.   parent_ = 0;
  91.   if (Fl_Group::current()) Fl_Group::current()->add(this);
  92. }
  93.  
  94. void Fl_Widget::resize(int X, int Y, int W, int H) {
  95.   x_ = X; y_ = Y; w_ = W; h_ = H;
  96. }
  97.  
  98. // this is useful for parent widgets to call to resize children:
  99. int Fl_Widget::damage_resize(int X, int Y, int W, int H) {
  100.   if (x() == X && y() == Y && w() == W && h() == H) return 0;
  101.   resize(X, Y, W, H);
  102.   redraw();
  103.   return 1;
  104. }
  105.  
  106. int Fl_Widget::take_focus() {
  107.   if (!takesevents()) return 0;
  108.   if (!handle(FL_FOCUS)) return 0; // see if it wants it
  109.   if (contains(Fl::focus())) return 1; // it called Fl::focus for us
  110.   Fl::focus(this);
  111.   return 1;
  112. }
  113.  
  114. extern void fl_throw_focus(Fl_Widget*); // in Fl_x.C
  115.  
  116. // Destruction does not remove from any parent group!  And groups when
  117. // destroyed destroy all their children.  This is convienent and fast.
  118. // However, it is only legal to destroy a "root" such as an Fl_Window,
  119. // and automatic destructors may be called.
  120. Fl_Widget::~Fl_Widget() {
  121.   parent_ = 0; // kludge to prevent ~Fl_Group from destroying again
  122.   fl_throw_focus(this);
  123. }
  124.  
  125. // redraw this, plus redraw opaque object if there is an outside label
  126. static void redraw_label(Fl_Widget* w) {
  127.   w->redraw();
  128.   if (w->label() && (w->align()&15) && !(w->align() & FL_ALIGN_INSIDE)) {
  129.     for (Fl_Widget *p = w->parent(); p; p = p->parent())
  130.       if (p->box() || !p->parent()) {p->redraw(); break;}
  131.   }
  132. }
  133.  
  134. void Fl_Widget::activate() {
  135.   if (!active()) {
  136.     clear_flag(INACTIVE);
  137.     if (active_r()) {
  138.       redraw_label(this);
  139.       handle(FL_ACTIVATE);
  140.       if (inside(Fl::focus())) Fl::focus()->take_focus();
  141.     }
  142.   }
  143. }
  144.  
  145. void Fl_Widget::deactivate() {
  146.   if (active_r()) {
  147.     set_flag(INACTIVE);
  148.     redraw_label(this);
  149.     handle(FL_DEACTIVATE);
  150.     fl_throw_focus(this);
  151.   } else {
  152.     set_flag(INACTIVE);
  153.   }
  154. }
  155.  
  156. int Fl_Widget::active_r() const {
  157.   for (const Fl_Widget* o = this; o; o = o->parent())
  158.     if (!o->active()) return 0;
  159.   return 1;
  160. }
  161.  
  162. void Fl_Widget::show() {
  163.   if (!visible()) {
  164.     clear_flag(INVISIBLE);
  165.     if (visible_r()) {
  166.       redraw_label(this);
  167.       handle(FL_SHOW);
  168.       if (inside(Fl::focus())) Fl::focus()->take_focus();
  169.     }
  170.   }
  171. }
  172.  
  173. void Fl_Widget::hide() {
  174.   if (visible_r()) {
  175.     set_flag(INVISIBLE);
  176.     for (Fl_Widget *p = parent(); p; p = p->parent())
  177.       if (p->box() || !p->parent()) {p->redraw(); break;}
  178.     handle(FL_HIDE);
  179.     fl_throw_focus(this);
  180.   } else {
  181.     set_flag(INVISIBLE);
  182.   }
  183. }
  184.  
  185. int Fl_Widget::visible_r() const {
  186.   for (const Fl_Widget* o = this; o; o = o->parent())
  187.     if (!o->visible()) return 0;
  188.   return 1;
  189. }
  190.  
  191. // return true if widget is inside (or equal to) this:
  192. // Returns false for null widgets.
  193. int Fl_Widget::contains(const Fl_Widget *o) const {
  194.   for (; o; o = o->parent_) if (o == this) return 1;
  195.   return 0;
  196. }
  197.  
  198. //
  199. // End of "$Id: Fl_Widget.cxx,v 1.5 1999/01/07 19:17:29 mike Exp $".
  200. //
  201.